// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/*
 * @Author: qiulin_JXGM ql1746365080@gmail.com
 * @Date: 2024-10-16 09:35:57
 * @LastEditors: qiulin ql1746365080@gmail.com
 * @LastEditTime: 2024-12-12 15:14:22
 * @FilePath: \SGFEM\Import\BDFImport\BulkData\Material\MAT8Parser.cpp
 */
#include "Import/BDFImport/BulkData/Material/MAT8Parser.h"

#include <algorithm>
#include <cstdint>
#include <iostream>

#include "Utility/Logging/SGLogger.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Material/IOrthotropic2DMaterialService.h"

#include "Import/BDFImport/BDFParserBase.h"

BULKDATA_ENTRY_PARSER_REG (MAT8);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::DataStructure;
/*
// file://./../../Doc/MarkDown/BulkData/MAT8/MAT8.md>
*/
enum MAT8key : std::uint8_t
{
    MAT8key_MID = 2,     // 材料识别号
    MAT8key_E1,          // X方向的弹性模量
    MAT8key_E2,          // Y方向的弹性模量
    MAT8key_NU12,        // 泊松比
    MAT8key_G12,         // 平面内剪切模量
    MAT8key_G1Z,         // 1-Z平面内的横向剪切模量
    MAT8key_G2Z,         // 2-Z平面内的横向剪切模量
    MAT8key_RHO,         // 质量密度
    MAT8key_A1 = 12,     // X方向的热膨胀系数
    MAT8key_A2,          // Y方向的热膨胀系数
    MAT8key_TREF,        // 参考温度
    MAT8key_Xt,          // 纵向拉伸应力
    MAT8key_Xc,          // 纵向压缩应力
    MAT8key_Yt,          // 横向拉伸应力
    MAT8key_Yc,          // 横向压缩应力
    MAT8key_S,           // 平面剪切应力
    MAT8key_GE = 22,     // 结构阻尼系数
    MAT8key_F12,         // Tsai-Wu理论中的交互项
    MAT8key_STRN,        // 最大应变理论
    MAT8key_HFAIL = 32,  // Hashin失效准则关键字
    MAT8key_HF1,         // 最大纤维拉伸应力
    MAT8key_HF2,         // 最大纤维压缩应力
    MAT8key_HF3,         // 最大基体拉伸应力
    MAT8key_HF4,         // 最大基体压缩应力
    MAT8key_HF10,        // 最大平面剪切应力
    MAT8key_HF11,        // 最大横向剪切应力
    MAT8key_HTAPE = 42,  // Hashin-Tape准则关键字
    MAT8key_HT1,         // 最大带材纤维拉伸应力
    MAT8key_HT2,         // 最大带材纤维压缩应力
    MAT8key_HT3,         // 最大带材交叉纤维拉伸应力
    MAT8key_HT4,         // 最大带材交叉纤维压缩应力
    MAT8key_HT5,         // 最大带材厚度拉伸应力
    MAT8key_HT6,         // 带材厚度应力的贡献因子
    MAT8key_HT10,        // 最大平面剪切应力
    MAT8key_H11 = 53,    // Hashin-Tape准则其他关键字
    MAT8key_HT12,        // 最大z-x横向剪切应力
    MAT8key_HFABR = 62,  // Hashin-Fabric准则关键字
    MAT8key_HFB1,        // 最大第一纤维拉伸应力
    MAT8key_HFB2,        // 最大第一纤维压缩应力
    MAT8key_HFB3,        // 最大第二纤维拉伸应力
    MAT8key_HFB4,        // 最大第二纤维压缩应力
    MAT8key_HFB5,        // 最大厚度拉伸应力
    MAT8key_HFB6,        // 最大厚度压缩应力
    MAT8key_HFB10,       // 最大平面剪切应力
    MAT8key_HFB11 = 73,  // 最大横向剪切应力
    MAT8key_HFBT12,      // 最大z-x横向剪切应力
};

Common::Status BDF::BULKDATA::ParseMAT8 (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                         std::vector<std::string>&                               dividedEntryInfo)
{
    // 创建一个用于保存MAT8材料数据的临时结构体对象
    FEM::Orthotropic2DMaterial tempData;

    // TODO(bug 001) 填写m_domainId的正确值
    // 目前m_domainId硬编码为1，需要进一步确认是否正确
    tempData.m_domainId = 1;

    int curIDKey = 1;  // 当前处理的条目索引

    // 遍历所有分割后的条目信息
    for (auto curStrKey : dividedEntryInfo)
    {
        // 检查当前条目是否为空
        bool const isEmpty = is_all_space (curStrKey);
        if (isEmpty)
        {
            curIDKey++;
            continue;
        }

                // 根据条目ID，将解析后的数值存入对应的MAT8字段
        switch (curIDKey)
        {
        case MAT8key_MID:
            tempData.m_id = convertToI64 (curStrKey);
            break;
        case MAT8key_E1:
            tempData.m_E1 = convertToReal (curStrKey);
            break;
        case MAT8key_E2:
            tempData.m_E2 = convertToReal (curStrKey);
            break;
        case MAT8key_NU12:
            tempData.m_nu12 = convertToReal (curStrKey);
            break;
        case MAT8key_G12:
            tempData.m_G12 = convertToReal (curStrKey);
            break;
        case MAT8key_G1Z:
            tempData.m_G1Z = convertToReal (curStrKey);
            break;
        case MAT8key_G2Z:
            tempData.m_G2Z = convertToReal (curStrKey);
            break;
        case MAT8key_RHO:
            tempData.m_rho = convertToReal (curStrKey);
            break;
        case MAT8key_A1:
            tempData.m_A1 = convertToReal (curStrKey);
            break;
        case MAT8key_A2:
            tempData.m_A2 = convertToReal (curStrKey);
            break;
        case MAT8key_TREF:
            tempData.m_tref = convertToReal (curStrKey);
            break;
        case MAT8key_Xt:
            tempData.m_XT = convertToReal (curStrKey);
            tempData.m_XC = tempData.m_XT;
            break;
        case MAT8key_Xc:
            tempData.m_XC = convertToReal (curStrKey);
            break;
        case MAT8key_Yt:
            tempData.m_YT = convertToReal (curStrKey);
            tempData.m_YC = tempData.m_YT;
            break;
        case MAT8key_Yc:
            tempData.m_YC = convertToReal (curStrKey);
            break;
        case MAT8key_S:
            tempData.m_S = convertToReal (curStrKey);
            break;
        case MAT8key_GE:
            tempData.m_ge = convertToReal (curStrKey);
            break;
        case MAT8key_F12:
            tempData.m_F12 = convertToReal (curStrKey);
            break;
        case MAT8key_STRN:
            tempData.m_Strn = convertToReal (curStrKey);
            break;
        case MAT8key_HFAIL:
            break;
        case MAT8key_HF1:
            tempData.m_HFAILFactor[0] = convertToReal (curStrKey);
            tempData.m_HFAILFactor[1] = tempData.m_HFAILFactor[0];
            break;
        case MAT8key_HF2:
            tempData.m_HFAILFactor[1] = convertToReal (curStrKey);
            break;
        case MAT8key_HF3:
            tempData.m_HFAILFactor[2] = convertToReal (curStrKey);
            tempData.m_HFAILFactor[3] = tempData.m_HFAILFactor[2];
            break;
        case MAT8key_HF4:
            tempData.m_HFAILFactor[3] = convertToReal (curStrKey);
            break;
        case MAT8key_HF10:
            tempData.m_HFAILFactor[4] = convertToReal (curStrKey);
            tempData.m_HFAILFactor[5] = tempData.m_HFAILFactor[4];
            break;
        case MAT8key_HF11:
            tempData.m_HFAILFactor[5] = convertToReal (curStrKey);
            break;
        case MAT8key_HTAPE:
            break;
        case MAT8key_HT1:
            tempData.m_HTAPEFactor[0] = convertToReal (curStrKey);
            tempData.m_HTAPEFactor[1] = tempData.m_HTAPEFactor[0];
            break;
        case MAT8key_HT2:
            tempData.m_HTAPEFactor[1] = convertToReal (curStrKey);
            break;
        case MAT8key_HT3:
            tempData.m_HTAPEFactor[2] = convertToReal (curStrKey);
            tempData.m_HTAPEFactor[3] = tempData.m_HTAPEFactor[2];
            break;
        case MAT8key_HT4:
            tempData.m_HTAPEFactor[3] = convertToReal (curStrKey);
            break;
        case MAT8key_HT5:
            tempData.m_HTAPEFactor[4] = convertToReal (curStrKey);
            break;
        case MAT8key_HT6:
            tempData.m_HTAPEFactor[5] = convertToReal (curStrKey);
            break;
        case MAT8key_HT10:
            tempData.m_HTAPEFactor[6] = convertToReal (curStrKey);
            tempData.m_HTAPEFactor[7] = tempData.m_HTAPEFactor[6];
            tempData.m_HTAPEFactor[8] = tempData.m_HTAPEFactor[7];
            break;
        case MAT8key_H11:
            tempData.m_HTAPEFactor[7] = convertToReal (curStrKey);
            tempData.m_HTAPEFactor[8] = tempData.m_HTAPEFactor[7];
            break;
        case MAT8key_HT12:
            tempData.m_HTAPEFactor[8] = convertToReal (curStrKey);
            break;
        case MAT8key_HFABR:
            break;
        case MAT8key_HFB1:
            tempData.m_HFABRFactor[0] = convertToReal (curStrKey);
            tempData.m_HFABRFactor[1] = tempData.m_HFABRFactor[0];
            break;
        case MAT8key_HFB2:
            tempData.m_HFABRFactor[1] = convertToReal (curStrKey);
            break;
        case MAT8key_HFB3:
            tempData.m_HFABRFactor[2] = convertToReal (curStrKey);
            tempData.m_HFABRFactor[3] = tempData.m_HFABRFactor[2];
            break;
        case MAT8key_HFB4:
            tempData.m_HFABRFactor[3] = convertToReal (curStrKey);
            break;
        case MAT8key_HFB5:
            tempData.m_HFABRFactor[4] = convertToReal (curStrKey);
            tempData.m_HFABRFactor[5] = tempData.m_HFABRFactor[4];
            break;
        case MAT8key_HFB6:
            tempData.m_HFABRFactor[5] = convertToReal (curStrKey);
            break;
        case MAT8key_HFB10:
            tempData.m_HFABRFactor[6] = convertToReal (curStrKey);
            tempData.m_HFABRFactor[7] = tempData.m_HFABRFactor[6];
            tempData.m_HFABRFactor[8] = tempData.m_HFABRFactor[7];
            break;
        case MAT8key_HFB11:
            tempData.m_HFABRFactor[7] = convertToReal (curStrKey);
            tempData.m_HFABRFactor[8] = tempData.m_HFABRFactor[7];
            break;
        case MAT8key_HFBT12:
            tempData.m_HFABRFactor[8] = convertToReal (curStrKey);
            break;
        default:
            break;
        }
        curIDKey++;
    }

    // 将解析后的MAT8数据通过数据库服务工厂的Orthotropic2DMaterial服务添加到数据库中
    return dbServiceFactory->get<IOrthotropic2DMaterialService> ()->Add (tempData);
}